class: center, middle, inverse, title-slide .title[ #
] .author[ ### ] --- class: animated, fadeIn # Outline #### **1. Gramática de los gráficos** - Tidy data #### **2. Gráficos con `ggplot2`** - Boxplot - Histograma - Scatterplot #### **3. LibrerÃas especializadas** <style> .title-slide { background-image: url('img/1.png'); background-size: 100%; } </style> --- layout: false class: left, bottom, inverse, animated, bounceInDown # 01 ## La gramática de los gráficos --- layout: true class: animated, fadeIn --- # ¿Qué es la visualización de datos? - La **visualización de datos** es la **representación gráfica** de los **datos** - El objetivo principal es **comunicar información de manera clara** y **efectiva** - La **funcionalidad** y la **estética** han de ir de la mano <center> <img src="data:image/png;base64,#img/data_insights.png" align="middle" width="40%" margin="0 auto" /> </center> --- .pull-left[<img src="img/Ggplot2_hex_logo.png"></img>] .pull-right[ <br> <br> `ggplot2` es un popular paquete de visualización de datos de código abierto para el **lenguaje de programación R**. <br> Fue desarrollado por **Hadley Wickham** y se basa en la **gramática de gráficos**, que proporciona un marco coherente y sistemático para crear una amplia gama de visualizaciones de datos. <br><b> 1. Capas (Layering) 2. Flexibilidad 3. Reproducibilidad 4. Comunidad ] --- # La gramática de los gráficos .pull-left[ #### Gramática original <i class="fas fa-book"></i> Wilkinson, Leland. The grammar of graphics. Springer Science & Business Media, 2006. ] .pull-right[ <center> <img src="img/books_ggplot.png" width="80%"></img> ] -- #### Adaptado a `R` en el paquete `ggplot2` <i class="fas fa-book"></i> Hadley Wickham. ggplot2: elegant graphics for data analysis. Springer, 2009. "La gramática nos dice que un **gráfico estadÃstico** es un **mapeo** de **datos** a **atributos estéticos** (color, forma, tamaño) de **objetos geométricos** (puntos, lÃneas, barras). El gráfico también puede contener **transformaciones estadÃsticas** de los datos y se dibuja en un **sistema de coordenadas especÃfico**. Es la **combinación de estos componentes independientes lo que forma un gráfico**." --- ## Sintaxis En `ggplot2` hay diferentes componentes que podemos añadir a un gráfico: .pull-left[ ```r ggplot(data = <DATA>, mapping = aes(<MAPPINGS>)) + <GEOM_FUNCTION>(stat = <STAT>, position = <POSITION>) + <SCALE_FUNCTION>() + <COORDINATE_FUNCTION>() + <FACET_FUNCTION>() + <THEME_FUNCTION> ``` ] <img src="img/ggplot2layers2019_8_10D11_28_23.png" width="52%" style="position: absolute; right: 50px; top: 25%;"> <center> <p style="position:absolute; bottom:125px; right:200px;"> Grammar of Graphics:<br>A layered approach to elegant visuals </p> --- ### Datos ordenados (tidy data) Data frames con una observación por fila y una variable por columna. <center> <img src="data:image/png;base64,#img/tidy-1.png" alt="Bokeh plots" width="900"/> </center> --- ### Datos ordenados (tidy data) Dos tipos de estructuras de datos ordenados: * **Formato ancho** (el más común): en un formato ancho, las múltiples medidas de una sola observación se almacenan en una sola fila. ``` ## Student Math Literature PE ## 1 A 99 45 56 ## 2 B 73 78 55 ## 3 C 12 96 57 ``` -- * **Formato largo**: cada fila corresponde a una medida de una observación. ``` ## # A tibble: 9 × 3 ## Student Subject Score ## <chr> <chr> <dbl> ## 1 A Math 99 ## 2 A Literature 45 ## 3 A PE 56 ## 4 B Math 73 ## 5 B Literature 78 ## 6 B PE 55 ## 7 C Math 12 ## 8 C Literature 96 ## 9 C PE 57 ``` --- ### Datos ordenados (tidy data) Existen funciones para cambiar del formato ancho al formato largo: ``` r # Paquete tidyverse, función pivot_longer library(tidyverse) long_df <- pivot_longer( wide_df, cols = c(Math, Literature, PE), # o cols = -c(Student), names_to = "Subject", values_to = "Score" ) long_df ``` ``` ## # A tibble: 9 × 3 ## Student Subject Score ## <chr> <chr> <dbl> ## 1 A Math 99 ## 2 A Literature 45 ## 3 A PE 56 ## 4 B Math 73 ## 5 B Literature 78 ## 6 B PE 55 ## 7 C Math 12 ## 8 C Literature 96 ## 9 C PE 57 ``` --- class: animated, fadeIn # Trabajando con datos Leeremos los datos que corresponden a casos de una epidemia de ébola simulada (obtenidos de: https://www.epirhandbook.com/). En R, una tabla se llama **data.frame**. ``` r surv_raw <- read_tsv("data/ebola_epidemic.tab", col_names = T) ``` <div style="font-size: 60%;">
</div> --- layout: false class: left, bottom, inverse, animated, bounceInDown # 02 ## Gráficos con `ggplot2` --- class: animated, fadeIn ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. ``` ## # A tibble: 3 × 2 ## outcome n_rows ## <chr> <int> ## 1 Death 2582 ## 2 Recover 1983 ## 3 <NA> 1323 ``` Primero, indicamos los datos (el **dataframe**): ``` r *ggplot(data = surv_raw) ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-8-1.png" width="432" /> ] --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Después, indicamos las variables que usamos para los ejes `x` e `y`: ``` r ggplot(data = surv_raw, * mapping = aes(x = outcome, y = age)) ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-10-1.png" width="432" /> ] --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Indicamos de qué tipo es el gráfico, en este caso, haremos un boxplot: ``` r ggplot(data = surv_raw, mapping = aes(x = outcome, y = age)) + * geom_boxplot() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-12-1.png" width="432" /> ] --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Podemos usar la función `drop_na()` para eliminar los casos NA (no tenemos información de la edad): ``` r *library(tidyr) *ggplot(data = surv_raw %>% drop_na(outcome), mapping = aes(x = outcome, y = age)) + geom_boxplot() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-14-1.png" width="432" /> ] --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Con `fill`, indicamos que queremos colorear según el grupo de `outcome`. ``` r ggplot(data = surv_raw %>% drop_na(outcome), mapping = aes(x = outcome, y = age, * fill = outcome)) + geom_boxplot() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-16-1.png" width="432" /> ] --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Con `scale_fill_manual`, indicamos que de manera manual asignaremos los colores que queremos usar: ``` r ggplot(data = surv_raw %>% drop_na(outcome), mapping = aes(x = outcome, y = age, fill = outcome)) + geom_boxplot() + * scale_fill_manual( * values = c("Death" = "aquamarine4", * "Recover" = "bisque4")) ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-18-1.png" width="432" /> ] Puedes consultar la guÃa de colores aquÃ: https://r-charts.com/colors/ --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Podemos aplicar un tema con `theme_*`: ``` r ggplot(data = surv_raw %>% drop_na(outcome), mapping = aes(x = outcome, y = age, fill = outcome)) + geom_boxplot() + scale_fill_manual( values = c("Death" = "aquamarine4", "Recover" = "bisque4")) + * theme_minimal() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-20-1.png" width="432" /> ] Puedes consultar los temas disponibles en: https://ggplot2.tidyverse.org/reference/ggtheme.html --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Con `labs()`, indicamos los tÃtulos para los ejes y un tÃtulo general. ``` r ggplot(data = surv_raw %>% drop_na(outcome), mapping = aes(x = outcome, y = age, fill = outcome)) + geom_boxplot() + scale_fill_manual( values = c("Death" = "aquamarine4", "Recover" = "bisque4")) + theme_minimal() + * labs(y = "Age", x = "Outcome", * title = "Boxplot by outcome") ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-22-1.png" width="432" /> ] --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Con `theme()`, podemos aplicar **cualquier** modificación al gráfico (¡avanzado!). Por ejemplo, indicar que no queremos la leyenda. ``` r ggplot(data = surv_raw %>% drop_na(outcome), mapping = aes(x = outcome, y = age, fill = outcome)) + geom_boxplot() + scale_fill_manual( values = c("Death" = "aquamarine4", "Recover" = "bisque4")) + theme_minimal() + labs(y = "Age", x = "Outcome", title = "Boxplot by outcome") + * theme(legend.position = "none") ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-24-1.png" width="432" /> ] --- ## Cómo hacer boxplots avanzados? .pull-left[ Queremos representar la edad (`age`) de los grupos de `outcome` de nuestra tabla `surv_raw`. Podemos agregar la significancia con el paquete `ggsignif`. ``` r library(ggsignif) ggplot(data = surv_raw %>% drop_na(outcome), mapping = aes(x = outcome, y = age, fill = outcome)) + geom_boxplot() + scale_fill_manual( values = c("Death" = "aquamarine4", "Recover" = "bisque4")) + theme_minimal() + labs(y = "Age", x = "Outcome", title = "Boxplot by outcome") + theme(legend.position = "none") + * geom_signif(comparisons = * list(c("Death", "Recover")), * test = "wilcox.test") ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-26-1.png" width="432" /> ] --- ## Cómo hacer un histograma avanzado? .pull-left[ Queremos hacer una curva epidémica para cada hospital. ``` r *ggplot(data = surv_raw) ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-28-1.png" width="432" /> ] --- ## Cómo hacer un histograma avanzado? .pull-left[ Queremos hacer una curva epidémica para cada hospital. ``` r ggplot(data = surv_raw) + * geom_histogram(aes(x = date_onset)) ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-30-1.png" width="432" /> ] --- ## Cómo hacer un histograma avanzado? .pull-left[ Queremos hacer una curva epidémica para cada hospital. ``` r ggplot(data = surv_raw) + geom_histogram(aes(x = date_onset, fill = hospital)) + * scale_fill_brewer(type = "qual", * palette = 1) ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-32-1.png" width="432" /> ] Hemos utilizado una paleta de colores preexistente. Puedes consultarlas en: https://ggplot2.tidyverse.org/reference/scale_brewer.html --- ## Cómo hacer un histograma avanzado? .pull-left[ Queremos hacer una curva epidémica para cada hospital. ``` r ggplot(data = surv_raw) + geom_histogram(aes(x = date_onset, fill = hospital)) + scale_fill_brewer(type = "qual", palette = 1) + * theme_minimal() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-34-1.png" width="432" /> ] --- ## Cómo hacer un histograma avanzado? .pull-left[ Queremos hacer una curva epidémica para cada hospital. ``` r ggplot(data = surv_raw) + geom_histogram(aes(x = date_onset, fill = hospital)) + scale_fill_brewer(type = "qual", palette = 1) + theme_minimal() + * theme(legend.position = "bottom") ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-36-1.png" width="432" /> ] --- ## Cómo hacer un histograma avanzado? .pull-left[ Queremos hacer una curva epidémica para cada hospital. ``` r ggplot(data = surv_raw) + geom_histogram(aes(x = date_onset, fill = hospital)) + scale_fill_brewer(type = "qual", palette = 1) + theme_minimal() + theme(legend.position = "bottom") + * labs(x = "Onset date", y = "", * title = "Epidemic curve") ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-38-1.png" width="432" /> ] --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. ``` r library(dplyr) # Calcular los cuantiles para 5 grupos q <- seq(0, 1, 1/5) age_quints <- quantile(surv_raw$age, probs = q, na.rm = TRUE) age_quints ``` ``` ## 0% 20% 40% 60% 80% 100% ## 0 5 10 17 26 84 ``` ``` r # Crear etiquetas con los rangos de edad age_labels <- paste0("(",age_quints[-length(age_quints)], "-", age_quints[-1],"]") age_labels ``` ``` ## [1] "(0-5]" "(5-10]" "(10-17]" "(17-26]" "(26-84]" ``` --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. ``` r # Crear la columna age_cat_5 con etiquetas de rango surv_raw <- surv_raw %>% mutate(age_cat_5 = cut(age, breaks = age_quints, include.lowest = TRUE, labels = age_labels)) surv_raw[,c("case_id", "age", "age_cat_5")] ``` ``` ## # A tibble: 5,888 × 3 ## case_id age age_cat_5 ## <chr> <dbl> <fct> ## 1 5fe599 2 (0-5] ## 2 8689b7 3 (0-5] ## 3 11f8ea 56 (26-84] ## 4 b8812a 18 (17-26] ## 5 893f25 3 (0-5] ## 6 be99c8 16 (10-17] ## 7 07e3e8 16 (10-17] ## 8 369449 0 (0-5] ## 9 f393b4 61 (26-84] ## 10 1389ca 27 (26-84] ## # ℹ 5,878 more rows ``` --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. .pull-left[ ``` r ggplot(surv_raw, * aes(x = ht_cm, y = wt_kg)) ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-42-1.png" width="432" /> ] --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. .pull-left[ ``` r ggplot(surv_raw, aes(x = ht_cm, y = wt_kg)) + * geom_point() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-44-1.png" width="432" /> ] --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. .pull-left[ ``` r ggplot(surv_raw, aes(x = ht_cm, y = wt_kg, * color=age_cat_5)) + geom_point() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-46-1.png" width="432" /> ] --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. .pull-left[ ``` r ggplot(surv_raw, aes(x = ht_cm, y = wt_kg, color=age_cat_5, * shape=age_cat_5)) + geom_point() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-48-1.png" width="432" /> ] --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. .pull-left[ ``` r ggplot(surv_raw, aes(x = ht_cm, y = wt_kg, color=age_cat_5, shape=age_cat_5)) + geom_point() + labs(title = "Relación peso-altura", x = "Altura (cm)", y = "Peso (kg)") + * scale_color_brewer(palette = "Set2") + theme_minimal() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-50-1.png" width="432" /> ] --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. .pull-left[ ``` r *ggplot(surv_raw %>% drop_na(age_cat_5), aes(x = ht_cm, y = wt_kg, color=age_cat_5, shape=age_cat_5)) + geom_point() + labs(title = "Relación peso-altura", x = "Altura (cm)", y = "Peso (kg)") + scale_color_brewer(palette = "Set2") + theme_minimal() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-52-1.png" width="432" /> ] --- ## Cómo hacer un scatterplot? Queremos representar la relación entre altura y peso de los pacientes. .pull-left[ ``` r ggplot(surv_raw %>% drop_na(age_cat_5), aes(x = ht_cm, y = wt_kg, color=age_cat_5, shape=age_cat_5)) + geom_point() + labs(title = "Relación peso-altura", x = "Altura (cm)", y = "Peso (kg)", * color="CategorÃa edad", * shape="CategorÃa edad") + scale_color_brewer(palette = "Set2") + theme_minimal() ``` ] .pull-right[ <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-54-1.png" width="432" /> ] --- layout: false class: left, bottom, inverse, animated, bounceInDown # 03 ## LibrerÃas especializadas --- layout: true class: animated, fadeIn --- # Bibliotecas y software especializados - Paquetes de software integrados - Javascript + [BioJS](https://biojs.net) - Bibliotecas de R + Repositorios especializados [Bioconductor](https://bioconductor.org) + Extensiones de [`ggplot2`](https://exts.ggplot2.tidyverse.org/) + [`htmlwidgets`](http://gallery.htmlwidgets.org/), algunos utilizando bibliotecas de BioJS --- ## Estructuras anatómicas: `gganatogram` https://github.com/jespermaag/gganatogram ``` r library(gganatogram) gganatogram(data=organ_df, fillOutline='#a6bddb', organism='human', sex='female', fill="value") + scale_fill_gradient(low = "white", high = "red") + facet_wrap(~ type) ``` <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-56-1.png" width="561.6" /> --- ## Logos: `ggseqlogo` https://omarwagih.github.io/ggseqlogo/ ``` r library(ggseqlogo) ggplot() + geom_logo(seqs_dna$MA0002.1) + theme_logo() + labs(title = "My TFBS profile") ggplot() + annotate(geom = "rect", xmin = 2.5, xmax = 4.5, ymin = -Inf, ymax = Inf, alpha = 0.2) + geom_logo(seqs_dna$MA0008.1, method = "probability") + theme_logo() ``` <img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-58-1.png" width="324" /><img src="data:image/png;base64,#3.VisualizacionDatos_files/figure-html/unnamed-chunk-58-2.png" width="324" /> --- ## Estructuras de genes: `gggenes` y `gggenomes` https://github.com/wilkox/gggenes - https://thackl.github.io/gggenomes/ .pull-left[ ``` r library(gggenes) ggplot(example_genes, aes(xmin = start, xmax = end, y = molecule, fill = gene)) + geom_feature( data = example_features, aes(x = position, y = molecule, forward = forward) ) + geom_feature_label( data = example_features, aes(x = position, y = molecule, label = name, forward = forward) ) + geom_gene_arrow() + geom_blank(data = example_dummies) + facet_wrap(~ molecule, scales = "free", ncol = 1) + scale_fill_brewer(palette = "Set3") + theme_genes() ``` ] .pull-right[ <img src="img/Captura.PNG" width=100%> <small> Figure 7 - Tahami, M.S., Vargas-Chavez, C., Poikela, N., Coronado-Zamora, M., et al. Transposable elements in Drosophila montana from harsh cold environments. Mobile DNA 15, 18 (2024). https://doi.org/10.1186/s13100-024-00328-7 ] --- # Resumen - La mayorÃa de los gráficos exploratorios y de comunicación básicos en biologÃa se pueden generar con herramientas generales de gráficos estadÃsticos (`ggplot2`) --> Datos cuantitativos y cualitativos - Diagramas de dispersión (scatterplots) - Diagramas de barras (barplots) - Diagramas de caja (boxplots) - Histoggramas - Mapas de calor (heatmaps), ... - La complejidad y las caracterÃsticas de algunos datos biológicos requieren herramientas especializadas. + Si los requisitos son estáticos, las extensiones de `ggplot2` pueden ser útiles. + Revisa las herramientas utilizadas en estudios similares.